package pl.asoft.nbp.service.impl;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import pl.asoft.nbp.exception.SystemException;
import pl.asoft.nbp.model.ExchangeRate;
import pl.asoft.nbp.service.NbpService;
import pl.asoft.nbp.util.DocumentParser;
import pl.asoft.nbp.util.LinkCreator;
import pl.asoft.nbp.util.SiteRunner;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLConnection;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static pl.asoft.nbp.util.DateConverter.convertDate;
import static pl.asoft.nbp.validator.ExchangeRateValidator.validateShortName;

/**
 * Created by rbiedrawa on 2014-12-01.
 */
@Service("nbpService")
public class NbpServiceImpl implements NbpService {
    private static final Logger LOG = Logger.getLogger(NbpServiceImpl.class);
    private static final String URL_A = "http://www.nbp.pl/kursy/xml/LastA.xml";

    private DocumentParser parser;

    public NbpServiceImpl() {
        parser = new DocumentParser();
    }

    @Override
    public ExchangeRate getExchangeRate(String currency) {
        validateShortName(currency.toUpperCase());
        parser.parse(URL_A, currency.toUpperCase());
        Collection<ExchangeRate> exchangeRateTable = parser.getExchangeRateTable();

        return exchangeRateTable.iterator().next();
    }

    @Override
    public Collection<ExchangeRate> getExchangeRate(String currency, Date startDate, Date endDate) {
        if(startDate == null && endDate == null){
            parser.parse(URL_A, currency.toUpperCase());
            Collection<ExchangeRate> exchangeRateTable = parser.getExchangeRateTable();
            return exchangeRateTable;
        }
        validateShortName(currency.toUpperCase());
        List<String> allDays = convertDate(startDate, endDate);

        SiteRunner siteRunner = null;
        // Hardcoded letter 'a'  for Kursy obce
        siteRunner = new SiteRunner(createLinks(URL_DIR, allDays, "a"), currency.toUpperCase());

        if (siteRunner != null) {
            siteRunner.start();
        }
        return siteRunner.getResults();
    }

    private List<String> createLinks(String dirURL, List<String> days, final String rateType) {
        List<String> matchedLinks;

        URLConnection connection = parser.openConnection(dirURL);

        try (BufferedReader br = new BufferedReader(new InputStreamReader(
                connection.getInputStream()))) {

            matchedLinks = br.lines().parallel().filter(e -> e.startsWith(rateType))
                    .collect(Collectors.toList());

        } catch (IOException e) {
            throw new SystemException(e.getMessage());
        }

        // starting the service that will loop days to find matchings
        LinkCreator service = new LinkCreator(days, matchedLinks);
        service.start();
        return service.getListOfValidLinks();

    }
}
